Velocity - Insert and Convert Using Velocity

Convert data using the Velocity Template.
About the details of the Velocity, please refer to https://velocity.apache.org/.

Stream Information

InputFormatAll
Number of InputsUnlimited
Description Data can be inserted into multiple streams directly.
Access to the input stream using the $in.array method.
OutputFormatText,XML,CSV,HTML

Component Properties

NameData TypeMappingDescription
Modechoice- Specify whether to specify the Velocity Template by file or input it directly.
The below property is decided by the selected methods. Once selected a method, the display of the property will be switched correspondingly.
File - Read data from an external file.
Inline - Read data from Template .
TemplatestringIn & Out If Mode is "Inline", input Velocity Template directly.
TemplateFilenameremoteFileIn & Out If Mode is File, specify the path of the Velocity Template.
You can specify the template path by the absolute path.
TemplateHomepathResolver- If Mode is "File", specify the base directory of the template file path.
Project Folder [Relative] - Set the folder where the project file is as start.
Home Folder [ProjectOwner] - Set the user home directory as start.
TemplateEncodingchoiceIn & Out If Mode is "File", specify the Velocity Template's encoding.
XPathVariablePrefixstringIn & Out If use variables in the XPath expression, specify a prefix.
VariablescategoryIn & Out Only specify a valid variable in the component.
In the Velocity Template, it can be referred as $local.
AddoncategoryIn & Out Add a java class to use in the template.
For example, to use VelocityTools's DateTool, by specifying "date" and "org.apache.velocity.tools.generic.DateTool" for Name and Class individually, it can be referred as $date in the Velocity Template. To specify a class, the constructor with parameters is needed.

To use an external library, please configure its jar file to [INSTALL_DIR]/flow/lib/userlib.
(When use VelocityTools, it's necessary to copy the jar file at the same place.)

Loop

This component cannot be the starting point for a loop.

Transaction

CommitDo nothing
RollbackDo nothing

Exceptions

TypeParameterStream for error handling flowError
Code
Description
Exception None This component's input stream - The template file cannot be found.
An exception was thrown during template processing, for example,syntax error.
1When the class specified for Addon 's Class cannot be found.
2When failed to the convert the class specified for Addon 's Class into instance.

Editing Page of Template

By double clicking the compoent or right clicking it to open a menu and clicking "Edit Template", you can open the editing page of the template.
You an set the details of the template, local variables and input stream etc. in this page.
You can also import a template from the list saved previously or preview test data.

the "Tempalte" Text Box

Describe the details of the template.
About the details of the template, if Mode is "Inline", the linefeed code specified in "Linefeed Code" will be saved in Template . If "Mode" is "File", the linefeed code specified in "Linefeed Code" will be saved in the specified file.

"Local Variable" Tab

You can set the Variables of inspector here.

"Input Stream" Tab

The stream definition of the preceding component can be set here.
The stream type can't be changed. If there isn't a preceding component or the stream type is Any, the tab won't be shown.

"Test Data" Tab

Specify the test data you want to use in preview.
If the input stream is Record, CSV, FixedLength or ParameterList, please specify the test data by CSV. If the input stream is XML or Text, please specify it by text.

If there is no input stream definition, the tab won't be shown. If the content of the test data isn't saved, when open the project again, it will be empty.

"Import from List", "Save to List" Button

After gathering the template content, local variable, input stream's field definition and test data into a set, you can name the set and save it. The saved data can be imported by the "Import from List" button at any time.

"Preview" Button

Display the preview of the result using the content of the template and test data. Because the preview file is created under the client environment, there are some restrictions as below.

Objects can be used in the template

Value(Value)

The variable and the field value of the record will be the value object.
The methods implemented in the value object are as below.

Method nameParameterReturn value typeDescription
strValue()NoneStringValue as String Type
intValue()NoneintValue as Integer Type
longValue()NonelongValue as Integer Type
doubleValue()NonedoubleValue as Double Type
decimalValue()NoneBigDecimalValue as Decimal Type
dateValue()NoneDateValue as DateTime Type
booleanValue()NonebooleanValue as Boolean Type
byteValue()Nonebyte[]Value as Binary Type
isNull()NonebooleanIf the value is null, True is returned.

The value object returns the value which is same as strValue() by itself.

Variable

Flow variables and the local variables defined by the component can be referred by the variable object individually.
You can refer to variables using the below reference marks.

Variable typesReference marks
Flow variables$flow.<flow variable name>
External variable set$exvar.<external variable set name>.<variable name>
System variable$system.<system variable name>(English name)
Local variable$local.<local variable name>

The below methods are implemented in the variable object.

MethodParameterReturn value typeDescription
get()String (variable name)ValueThe value corresponding with the variable is returned.
It's valid to describe variable name directly, like "$flow.var1".

Variable object returns the variable list by itself.
Namely, when only "$system" is recorded in the template, the list of the system variable will be output.

When refer to the undefined variable, by describing $flow.var1, it can be output without referring. In this case, if the variable can't be referred to after describing reference as $!{flow.var1}, system may output an empty string instead of outputting $flow.var1.

Sample
The value of Flow variable, "var1", is $flow.get("var1").
You can describe it as "$flow.var1" by omitting get.
#if ($flow.var2.intValue() == 1)
     Only when the value of the Flow variable "var2" is 1, the character can be output.
#end
#if ($exvar.exvar1.var3.strValue() == "abc")
    To compare string or number in if, it's necessary to organize the type of the object to be compared using strValue() and intValue().
    Although it is described as 「$exvar.exvar1.var3 == "abc"」, because the types to be compared are different, the result will be true.
#end

Stream Array

The streams input into the component are all stored in $in.
You can access to each stream using array method.
This object is Collection, so you can access to each stream using foreach.

Method nameParameterReturn value typeDescription
array()intStreamSpecify index and get input stream.
array()StringStreamSpecify component name or link name, and get input stream.
size()NoneintThe number of the streams included in the array.

$in returns the value which is got by converting the all stream information to strings.
If $in doesn't use its own method but use another method, it will forward to array(0).
Namely, the meaning of the format of "$in.array(0).〜" is as same as "$in.〜".

Stream (Stream)

It's input stream object. Except XML, all of the streams are included in this object.
You can access to each record of stream using the record method.

Method nameParameterReturn value typeDescription
recordsNoneCollectionReturn the Collection which is used to access to Record.
record()intRecordSpecify an index, and get a record.
text()NoneStringStream's string value.
size()NoneintThe number of the records included in the stream.
variable()StringValueReturn the stream variable.
variablenames()NoneIteratorReturn the iterator of the stream variable name.

Stream returns the value which is same as text().
If Stream doesn't use its own method but use another method, it will forward to record(0).
Namely, the meaning of the format of「$in.array(0).record(0).〜」 is as same as「$in.array(0).〜」.
When the input stream only has 1 ParameterList, it's convenient to write the marks in short like "$in.field1".

When get a stream variable, it can be described as below.

$in.variable("FilePath")

#set ($data = $in.array(2))
$data.variable("FilePath")

Record (Record)

It's a record object.
You can access to each field value of the record using field method.
Because the object will be a Collection, you can access to each field value using foreach.

Method nameParameterReturn value typeDescription
fieldsNoneCollectionReturn the Collection which is used to access to each field value.
field()intValueSpecify an index, and get a field value.
field()StringValueSpecify a field name and get a field value.
You can specify it as "field1" instead of writing "field("field1")".
name()intStringSpecify an index, and get a field name.
getNo()NoneintGet the line number of the record (based on 0).
size()NoneintThe number of the fields included in the record.

Record returns the value which is got by converting each field name and each field value into a string.

Example
---
$in.text()
---
$in.array(0).text()
---
$in.array("FileGet1")
---
When the input stream only has 1 FileGet1 Component, the above 3 output streams are the same.


#foreach ($data in $in)
    #foreach ($r in $data.records)
        $r.name(0) = $r.field(0)
        $r.name(1) = $r.field("Field2")
        $r.name(2) = $r.Field3
    #end
#end
---
When there are multiple input streams, you can access to the all streams and all records as above.
When there is only 1 stream, #foreach ($r in $in.records) is OK, too.

XML Stream

If the stream is XML, it will be an XML Stream.
For the XML stream, besides the common stream methods, you can also access to XML's Document using "doc" method as JDOM object.
About JDOM, please refer to http://www.jdom.org/.

Method nameParameterReturn value typeDescription
docNoneorg.jdom.DocumentJDOM's document object.
Example
$in.doc.rootElement.getChild("record").getChild("field").text
Show the value of the first child element "field" of the first child element "record" of document element.


#foreach ($r in $in.doc.rootElement.getChildren("record"))
  $r.getChild("field").text
#end
When there are multiple record elements, you can execute a loop by foreach.


If name space is used, you can take the Namespace as the 2nd parameter.
#set ($ns = $in.doc.rootElement.namespace )
#foreach ($r in $in.doc.rootElement.getChildren("record", $ns))
  $r.getChild("field", $ns).text
#end
if the record element and the name space of the field element are as same as the document element, you can get value as above.

XPath($xpath)

It's a utility class applied to XPath for the XML Stream.

Method nameParametersReturn value typeDescription
createXPath()StringXPathCreate an XPath object with taking the XPath expression as a parameter. Then, the XPath Class of JAXEN will be created.
booleanValueOf()String, ObjectbooleanSame as createXPath(expr).booleanValueOf(object).
numberValueOf()String, ObjectNumberSame as createXPath(expr).numberValueOf(object).
selectNodes()String, ObjectListSame as createXPath(expr).selectNodes(object).
selectSingleNode()String, ObjectObjectSame as createXPath(expr).selectSingleNode(object).
stringValueOf()String, ObjectStringSame as createXPath(expr).stringValueOf(object).
valueOf()String, ObjectObjectSame as createXPath(expr).valueOf(object).

The name space definition of the XPath expression is decided by the name space definition of the input XML Stream.

When refer to a variable in an XPath expression, as /root/field1[@name=$fv:flow.var1], you an add a prefix specified by the prefix property of the XPath expression to the variable.
As $flow.var1, if the variable without a prefix is used, the expression will be converted by Velocity before expressing to an XPath class.

Example
$xpath.stringValueOf("/root/record[1]/field[1]", $in.doc)
Get the value of the first field element of the first record element under the root element.

$xpath.booleanValueOf("count(/root/record)=5", $in.doc)
When there are 5 record elements under the root element, true will return.

#foreach ($r in $xpath.selectNodes("/root/record", $in.doc))
    $r.getChild("field").text
#end
Because List is returned in selectNodes, you can use foreach.

$xpath.stringValueOf("/root/record[@name='$flow.var1']/field", $in.doc)
After the above "$flow.var1" has been converted by Velocity, an XPath will be passed.
When you want to process a variable in the XPath,

As $xpath.stringValueOf("/root/record[@name=$fv:flow.var1]/field", $in.doc), 
you can add a prefix specified by the prefix property of the XPath expression and specify it.
Please pay attention that the variable of the former one is quoted by '', and the variable of the latter one isn't quoted.

$xpath.stringValueOf("/ns:root/ns:record[1]/ns:field", $in.doc)
The XPath for which the name space is used.
NamespacePrefix"ns" should be done by the field definition of the input stream.

$xpath.stringValueOf("field[1]", $in.doc.rootElement.getChild("record"))
By specifying an arbitrary Node for the 2nd parameter, you can use the XPath which takes that as context.

#set ($expr = $xpath.createXPath("field[1]"))
#foreach ($r in $in.rootDocument.getChildren("record"))
    $expr.stringValueOf($r)
#end
You can use all XPath objects created by createXPath in the loop.
"$expr.stringValueOf($r)" in loop is as same as $xpath.stringValueOf("field[1]", $r),
the part which doesn't create an XPath object every time is faster.

System($sys)

Some general functions are offered as the method of $sys.

Method nameParameterReturn value typeDescription
escape()Value or StringStringConvert ">", "<", "&", """ to "&gt;", "&lt;", "&amp;", "&quot;" individually in a string.
outputXML()org.jdom.DocumentStringConvert the JDOM document into a string.
outputXML()org.jdom.Document, booleanStringConvert the JDOM document into a string. The 2nd parameter represents that whether there is an indent or not.
outputXML()org.jdom.ElementStringConvert the JDOM Element into a string.
outputXML()org.jdom.Element, booleanStringConvert the JDOM element into a string. The 2nd parameter represents that whether there is an indent or not.
strToInt()StringintConvert a string into int.
strToDouble()StringdoubleConvert a string into double.
getCurrentDate()NoneDateReturn the current date and time.
formatDecimal()Value or an arbitrary number type, StringStringConvert the number of the 1st parameter to a string in the format of the 2nd parameter.
formatDate()Value or Date, StringStringConvert the date of the 1st parameter into a string in the format of the 2nd parameter.
regexpReplace()String, String, String, boolean, boolean, booleanStringReplace the part of the string of the 1st parameter which matches the regular expression of the 2nd parameter with the string of the 3rd parameter.Please specify whether to make the 4th parameter case-sensitive or not, whether to replace the all strings to be matched or not, whether the 6th parameter can use the meta character via the string of the 3rd parameter (REGEXPREPLACErefer to a function) or not. Under the default status, the 4th~6th parameters can execute, and the default value is true.

In the old version, the convertDomToString method can be replaced with the outputXML method by which you can specify whether there is an indent or not.
convertDomToString method can be used as before. From now on, please use outputXML.

Example
$sys.escape($in.text())
Escape the whole input stream and output.

$sys.outputXML($in.doc, true)
Indent the input XML and output it.

$sys.outputXML($in.doc.rootElement.getChild("record"))
Output the all data under the first record element of the input XML.

$sys.formatDate($sys.getCurrentDate(), "yyyy/MM/dd")
Format the current date and time, and output it.

#set ($num = 50000)
$num
$sys.formatDecimal($num, $local.FORMAT.strValue())
$sys.formatDecimal($flow.Num1, $local.FORMAT.strValue())
## In Velocity, "##" is defined as the first character of the comment line, the string in the format as "#,##0"
## can't be inserted into the template directly.
## When use the format like that, please use the methods for which Local variable is used.

$sys.regexpReplace($contents, "(s?https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+)", '<a href="$1">$1</a>')
Please replace the URL with a link in the string. (The regular expression of the above URL is simple.)

Output Encoding($encoding)

Output the encoding of the output stream.
Please use it when specify the charset of the HTML.

Remark